home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1989, 1990, 1991 by the University of Washington
- *
- * For copying and distribution information, please see the file
- * <copyright.h>.
- */
-
- /*
- * Miscellaneous routines pulled from ~beta/lib/pfs and ~beta/lib/filters
- */
-
- #include <stdio.h>
-
- #include <errno.h>
-
- #ifdef VMS
- # ifdef WOLLONGONG
- # include "twg$tcp:[netdist.include]netdb.h"
- # else /* not Wollongong */
- # ifdef UCX
- # include <netdb.h>
- # else /* Multinet */
- # include "multinet_root:[multinet.include]netdb.h"
- # endif
- # endif
- # include <vms.h>
- #else /* not VMS */
- # include <sys/types.h>
- # include <pmachine.h>
- # ifdef NEED_STRING_H
- # include <string.h>
- # else
- # include <strings.h>
- # endif
- # ifndef CUTCP
- # include <netdb.h>
- # endif
- # if !defined(MSDOS) || defined(OS2)
- # include <sys/file.h>
- # include <sys/param.h>
- # endif
- #endif /* VMS */
-
- #include <pfs.h>
- #include <pprot.h>
- #include <perrno.h>
- #include <pcompat.h>
- #include <pauthent.h>
-
- #include "regex.h"
-
- int pfs_enable = PMAP_ATSIGN;
-
- #ifndef FALSE
- # define TRUE 1
- # define FALSE 0
- #endif
-
- /*
- * wcmatch - Match string s against template containing widlcards
- *
- * WCMATCH takes a string and a template, and returns
- * true if the string matches the template, and
- * FALSE otherwise.
- *
- * ARGS: s - string to be tested
- * template - Template containing optional wildcards
- *
- * RETURNS: TRUE (non-zero) on match. FALSE (0) otherwise.
- *
- * NOTE: If template is NULL, will return TRUE.
- *
- */
- int
- wcmatch(s,template)
- char *s;
- char *template;
- {
- char temp[200];
- char *p = temp;
-
- if(!template) return(TRUE);
- *p++ = '^';
-
- while(*template) {
- if(*template == '*') {*(p++)='.'; *(p++) = *(template++);}
- else if(*template == '?') {*(p++)='.';template++;}
- else if(*template == '.') {*(p++)='\\';*(p++)='.';template++;}
- else if(*template == '[') {*(p++)='\\';*(p++)='[';template++;}
- else if(*template == '$') {*(p++)='\\';*(p++)='$';template++;}
- else if(*template == '^') {*(p++)='\\';*(p++)='^';template++;}
- else if(*template == '\\') {*(p++)='\\';*(p++)='\\';template++;}
- else *(p++) = *(template++);
- }
-
- *p++ = '$';
- *p++ = '\0';
-
- if(re_comp(temp)) return(FALSE);
-
- #ifdef AUX
- if (re_exec(s) == (char *)NULL)
- return 0;
- return 1;
- #else
- return(re_exec(s));
- #endif
- }
-
- /*
- * ul_insert - Insert a union link at the right location
- *
- * UL_INSERT takes a directory and a union link to be added
- * to a the list of union links in the directory. It then
- * inserts the union link in the right spot in the linked
- * list of union links associated with that directory.
- *
- * If an identical link already exists, then the link which
- * would be evaluated earlier (closer to the front of the list)
- * wins and the other one is freed. If this happens, an error
- * will also be returned.
- *
- * ARGS: ul - link to be inserted
- * vd - directory to get link
- * p - vl that this link will apper after
- * NULL - This vl will go at end of list
- * vd - This vl will go at head of list
- *
- * RETURNS: Success, or UL_INSERT_ALREADY_THERE or UL_INSERT_SUPERSEDING
- */
- int
- ul_insert(ul,vd,p)
- VLINK ul; /* Link to be inserted */
- PVDIR vd; /* Directory to receive link */
- VLINK p; /* Union link to appear prior to new one */
- {
- VLINK current;
-
- /* This is the first ul in the directory */
- if(vd->ulinks == NULL) {
- vd->ulinks = ul;
- ul->previous = NULL;
- ul->next = NULL;
- return(PSUCCESS);
- }
-
- /* This ul will go at the head of the list */
- if(p == (VLINK) vd) {
- ul->next = vd->ulinks;
- ul->next->previous = ul;
- vd->ulinks = ul;
- ul->previous = NULL;
- }
- /* Otherwise, decide if it must be inserted at all */
- /* If an identical link appears before the position */
- /* at which the new one is to be inserted, we can */
- /* return without inserting it */
- else {
- current = vd->ulinks;
-
- while(current) {
- /* p == NULL means we insert after last link */
- if(!p && (current->next == NULL))
- p = current;
-
- if(vl_comp(current,ul) == 0) {
- vlfree(ul);
- return(UL_INSERT_ALREADY_THERE);
- }
-
- if(current == p) break;
- current = current->next;
- }
-
- /* If current is null, p was not found */
- if(current == NULL)
- return(UL_INSERT_POS_NOTFOUND);
-
- /* Insert ul */
- ul->next = p->next;
- p->next = ul;
- ul->previous = p;
- if(ul->next) ul->next->previous = ul;
- }
-
- /* Check for identical links after ul */
- current = ul->next;
-
- while(current) {
- if(vl_comp(current,ul) == 0) {
- current->previous->next = current->next;
- if(current->next)
- current->next->previous = current->previous;
- vlfree(current);
- return(UL_INSERT_SUPERSEDING);
- }
- current = current->next;
- }
-
- return(PSUCCESS);
- }
-
- /*
- * vl_insert - Insert a directory link at the right location
- *
- * VL_INSERT takes a directory and a link to be added to a
- * directory and inserts it in the linked list of links for
- * that directory.
- *
- * If a link already exists with the same name, and if the
- * information associated with the new link matches that in
- * the existing link, an error is returned. If the information
- * associated with the new link is different, but the magic numbers
- * match, then the new link will be added as a replica of the
- * existing link. If the magic numbers do not match, the new
- * link will only be added to the list of "replicas" if the
- * allow_conflict flag has been set.
- *
- * If the link is not added, an error is returned and the link
- * is freed. Ordering for the list of links is by the link name.
- *
- * If vl is a union link, then VL_INSERT calls ul_insert with an
- * added argument indicating the link is to be included at the
- * end of the union link list.
- *
- * ARGS: vl - Link to be inserted, vd - directory to get link
- * allow_conflict - insert links with conflicting names
- *
- * RETURNS: Success, or VL_INSERT_ALREADY_THERE
- */
- int
- vl_insert(vl,vd,allow_conflict)
- VLINK vl; /* Link to be inserted */
- PVDIR vd; /* Directory to receive link */
- int allow_conflict; /* Allow duplicate names */
- {
- VLINK current; /* To step through list */
- VLINK crep; /* To step through list of replicas */
- int retval; /* Temp for checking returned values */
-
- /* This can also be used to insert union links at end of list */
- if(vl->linktype == 'U') return(ul_insert(vl,vd,NULL));
-
- /* If this is the first link in the directory */
- if(vd->links == NULL) {
- vd->links = vl;
- vl->previous = NULL;
- vl->next = NULL;
- vd->lastlink = vl;
- return(PSUCCESS);
- }
-
- /* If no sorting is to be done, just insert at end of list */
- if(allow_conflict == VLI_NOSORT) {
- vd->lastlink->next = vl;
- vl->previous = vd->lastlink;
- vl->next = NULL;
- vd->lastlink = vl;
- return(PSUCCESS);
- }
-
- /* If it is to be inserted at start of list */
- if(vl_comp(vl,vd->links) < 0) {
- vl->next = vd->links;
- vl->previous = NULL;
- vl->next->previous = vl;
- vd->links = vl;
- return(PSUCCESS);
- }
-
- current = vd->links;
-
- /* Otherwise, we must find the right spot to insert it */
- while((retval = vl_comp(vl,current)) > 0) {
- if(!current->next) {
- /* insert at end */
- vl->previous = current;
- vl->next = NULL;
- current->next = vl;
- vd->lastlink = vl;
- return(PSUCCESS);
- }
- current = current->next;
- }
-
- /* If we found an equivilant entry already in list */
- if(!retval) {
- if(vl_equal(vl,current)) {
- vlfree(vl);
- return(VL_INSERT_ALREADY_THERE);
- }
- if((allow_conflict == VLI_NOCONFLICT) &&
- ((vl->f_magic_no != current->f_magic_no) ||
- (vl->f_magic_no==0)))
- return(VL_INSERT_CONFLICT);
- /* Insert the link into the list of "replicas" */
- /* If magic is 0, then create a pseudo magic number */
- if(vl->f_magic_no == 0) vl->f_magic_no = -1;
- crep = current->replicas;
- if(!crep) {
- current->replicas = vl;
- vl->next = NULL;
- vl->previous = NULL;
- }
- else {
- while(crep->next) {
- /* If magic was 0, then we need a unique magic number */
- if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
- (vl->f_magic_no)--;
- crep = crep->next;
- }
- /* If magic was 0, then we need a unique magic number */
- if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
- (vl->f_magic_no)--;
- crep->next = vl;
- vl->previous = crep;
- vl->next = NULL;
- }
- return(PSUCCESS);
- }
-
- /* We found the spot where vl is to be inserted */
- vl->next = current;
- vl->previous = current->previous;
- current->previous = vl;
- vl->previous->next = vl;
- return(PSUCCESS);
- }
-
- /*
- * nlsindex - Find first instance of string 2 in string 1 following newline
- *
- * NLSINDEX scans string 1 for the first instance of string
- * 2 that immediately follows a newline. If found, NLSINDEX
- * returns a pointer to the first character of that instance.
- * If no instance is found, NLSINDEX returns NULL (0).
- *
- * NOTE: This function is only useful for searching strings that
- * consist of multiple lines. s1 is assumed to be preceeded
- * by a newline. Thus, if s2 is at the start of s1, it will
- * be found.
- * ARGS: s1 - string to be searched
- * s2 - string to be found
- * RETURNS: First instance of s2 in s1, or NULL (0) if not found
- */
- char *
- nlsindex(s1,s2)
- char *s1; /* String to be searched */
- char *s2; /* String to be found */
- {
- register int s2len = strlen(s2);
- char *curline = s1; /* Pointer to start of current line */
-
- /* In case s2 appears at start of s1 */
- if(strncmp(curline,s2,s2len) == 0)
- return(curline);
-
- /* Check remaining lines of s1 */
- while((curline = (char *) index(curline,'\n')) != NULL) {
- curline++;
- if(strncmp(curline,s2,s2len) == 0)
- return(curline);
- }
-
- /* We didn't find it */
- return(NULL);
- }
-
- /*
- * month_sname - Return a month name from it's number
- *
- * MONTH_SNAME takes a number in the range 0
- * to 12 and returns a pointer to a string
- * representing the three letter abbreviation
- * for that month. If the argument is out of
- * range, MONTH_SNAME returns a pointer to "Unk".
- *
- * ARGS: n - Number of the month
- * RETURNS: Abbreviation for selected month
- */
- char *month_sname(n)
- int n; /* Month number */
- {
- static char *name[] = { "Unk",
- "Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec"
- };
- return((n < 1 || n > 12) ? name[0] : name[n]);
- }
-
- /*
- * sindex - Find first instance of string 2 in string 1
- *
- * SINDEX scans string 1 for the first instance of string
- * 2. If found, SINDEX returns a pointer to the first
- * character of that instance. If no instance is found,
- * SINDEX returns NULL (0).
- *
- * ARGS: s1 - string to be searched
- * s2 - string to be found
- * RETURNS: First instance of s2 in s1, or NULL (0) if not found
- */
- char *
- sindex(s1,s2)
- char *s1; /* String to be searched */
- char *s2; /* String to be found */
- {
- register int s2len = strlen(s2);
- char *s = s1; /* Temp pointer to string */
-
- /* Check for first character of s2 */
- while((s = (char *) index(s,*s2)) != NULL) {
- if(strncmp(s,s2,s2len) == 0)
- return(s);
- s++;
- }
-
- /* We didn't find it */
- return(NULL);
- }
-
- int
- scan_error(erst)
- char *erst;
- {
- *p_err_string = '\0';
-
- if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0)
- return(DIRSRV_NOT_DIRECTORY);
-
- if(strncmp(erst,"UNIMPLEMENTED",13) == 0) {
- perrno = DIRSRV_UNIMPLEMENTED;
- sscanf(erst+13,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string);
- return(perrno);
- }
-
- if(strncmp(erst,"WARNING ",8) == 0) {
- erst += 8;
- *p_warn_string = '\0';
- sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_warn_string);
- /* Return values for warnings are negative */
- if(strncmp(erst,"OUT-OF-DATE",11) == 0) {
- pwarn = PWARN_OUT_OF_DATE;
- return(PSUCCESS);
- }
- if(strncmp(erst,"MESSAGE",7) == 0) {
- pwarn = PWARN_MSG_FROM_SERVER;
- return(PSUCCESS);
- }
- pwarn = PWARNING;
- sscanf(erst,"%[^\n]",p_warn_string);
- return(PSUCCESS);
- }
- else if(strncmp(erst,"ERROR",5) == 0) {
- if(*(erst+5)) sscanf(erst+6,"%[^\n]",p_err_string);
- perrno = DIRSRV_ERROR;
- return(perrno);
- }
- /* The rest start with "FAILURE" */
- else if(strncmp(erst,"FAILURE",7) != 0) {
- /* Unrecognized - Give warning, but return PSUCCESS */
- if(pwarn == 0) {
- *p_warn_string = '\0';
- pwarn = PWARN_UNRECOGNIZED_RESP;
- sscanf(erst,"%[^\n]",p_warn_string);
- }
- return(PSUCCESS);
- }
-
- if(strncmp(erst,"FAILURE ",8) != 0) {
- perrno = PFAILURE;
- return(perrno);
- }
- erst += 8;
-
- sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string);
-
- /* Still to add */
- /* DIRSRV_AUTHENT_REQ 242 */
- /* DIRSRV_BAD_VERS 245 */
-
- if(strncmp(erst,"NOT-FOUND",9) == 0)
- perrno = DIRSRV_NOT_FOUND;
- else if(strncmp(erst,"NOT-AUTHORIZED",13) == 0)
- perrno = DIRSRV_NOT_AUTHORIZED;
- else if(strncmp(erst,"ALREADY-EXISTS",14) == 0)
- perrno = DIRSRV_ALREADY_EXISTS;
- else if(strncmp(erst,"NAME-CONFLICT",13) == 0)
- perrno = DIRSRV_NAME_CONFLICT;
- else if(strncmp(erst,"SERVER-FAILED",13) == 0)
- perrno = DIRSRV_SERVER_FAILED;
- /* Use it whether it starts with FAILURE or not */
- else if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0)
- perrno = DIRSRV_NOT_DIRECTORY;
- else perrno = PFAILURE;
-
- return(perrno);
- }
-
- PATTRIB
- parse_attribute(line)
- char *line;
- {
- char l_precedence[MAX_DIR_LINESIZE];
- char l_name[MAX_DIR_LINESIZE];
- char l_type[MAX_DIR_LINESIZE];
- char l_value[MAX_DIR_LINESIZE];
- PATTRIB at;
- int tmp;
-
- tmp = sscanf(line,"OBJECT-INFO %s %s %[^\n]", l_name, l_type, l_value);
-
- if(tmp < 3) {
- tmp = sscanf(line,"LINK-INFO %s %s %s %[^\n]", l_precedence,
- l_name, l_type, l_value);
- if(tmp < 4) {
- perrno = DIRSRV_BAD_FORMAT;
- return(NULL);
- }
- }
-
- at = atalloc();
-
- if(tmp == 4) {
- if(strcmp(l_precedence,"CACHED") == 0)
- at->precedence = ATR_PREC_CACHED;
- else if(strcmp(l_precedence,"LINK") == 0)
- at->precedence = ATR_PREC_LINK;
- else if(strcmp(l_precedence,"REPLACEMENT") == 0)
- at->precedence = ATR_PREC_REPLACE;
- else if(strcmp(l_precedence,"ADDITIONAL") == 0)
- at->precedence = ATR_PREC_ADD;
- }
-
- at->aname = stcopy(l_name);
- at->avtype = stcopy(l_type);
- if(strcmp(l_type,"ASCII") == 0)
- at->value.ascii = stcopy(l_value);
- else if(strcmp(l_type,"LINK") == 0) {
- char ftype[MAX_DIR_LINESIZE];
- char lname[MAX_DIR_LINESIZE];
- char htype[MAX_DIR_LINESIZE];
- char host[MAX_DIR_LINESIZE];
- char ntype[MAX_DIR_LINESIZE];
- char fname[MAX_DIR_LINESIZE];
- VLINK al;
-
- al = vlalloc();
- at->value.link = al;
-
- tmp = sscanf(l_value,"%c %s %s %s %s %s %s %d %d",
- &(al->linktype),
- ftype,lname,htype,host,ntype,fname,
- &(al->version),
- &(al->f_magic_no));
- if(tmp == 9) {
- al->type = stcopyr(ftype,al->type);
- al->name = stcopyr(unquote(lname),al->name);
- al->hosttype = stcopyr(htype,al->hosttype);
- al->host = stcopyr(host,al->host);
- al->nametype = stcopyr(ntype,al->nametype);
- al->filename = stcopyr(fname,al->filename);
- }
- else {
- perrno = DIRSRV_BAD_FORMAT;
- return(NULL);
- }
-
- }
-
- return(at);
- }
-
- /*
- * nxtline - Find the next line in the string
- *
- * NXTLINE takes a string and returns a pointer to
- * the character immediately following the next newline.
- *
- * ARGS: s - string to be searched
- *
- * RETURNS: Next line or NULL (0) on failure
- */
- char *
- nxtline(s)
- char *s; /* String to be searched */
- {
- s = (char *) index(s,'\n');
- if(s) return(++s);
- else return(NULL);
- }
-
-
- /*
- * unquote - unquote string if necessary
- *
- * UNQUOTE takes a string and unquotes it if it has been quoted.
- *
- * ARGS: s - string to be unquoted
- *
- * RETURNS: The original string. If the string has been quoted, then the
- * result appears in static storage, and must be copied if
- * it is to last beyond the next call to quote.
- *
- */
- char *
- unquote(s)
- char *s; /* String to be quoted */
- {
- static char unquoted[200];
- char *c = unquoted;
-
- if(*s != '\'') return(s);
-
- s++;
-
- /* This should really treat a quote followed by other */
- /* than a quote or a null as an error */
- while(*s) {
- if(*s == '\'') s++;
- if(*s) *c++ = *s++;
- }
-
- *c++ = '\0';
-
- return(unquoted);
- }
-
- #if defined(DEBUG) && defined(STRSPN)
- /* needed for -D option parsing */
- /*
- * strspn - Count initial characters from chrs in s
- *
- * STRSPN counts the occurances of chacters from chrs
- * in the string s preceeding the first occurance of
- * a character not in s.
- *
- * ARGS: s - string to be checked
- * chrs - string of characters we are looking for
- *
- * RETURNS: Count of initial characters from chrs in s
- */
- strspn(s,chrs)
- char *s; /* String to search */
- char *chrs; /* String of characters we are looking for */
- {
- char *cp; /* Pointer to the current character in chrs */
- int count; /* Count of characters seen so far */
-
- count = 0;
-
- while(*s) {
- for(cp = chrs;*cp;cp++)
- if(*cp == *s) {
- s++;
- count++;
- goto done;
- }
- return(count);
- done:
- ;
- }
- return(count);
- }
- #endif
-
- #ifdef CUTCP
- char
- *inet_ntoa(struct in_addr in)
- {
- static char buff[36];
-
- unsigned char *c = (char *) &in.address;
- sprintf(buff,"%d.%d.%d.%d",*c,*(c+1),*(c+2),*(c+3));
- return(buff);
- }
-
- long
- inet_addr(char *cp)
- {
- long value = 0;
- unsigned v1,v2,v3,v4;
-
- v1 = v2 = v3 = v4 = 0xff;
- sscanf(cp,"%d.%d.%d.%d",&v1,&v2,&v3,&v4);
- value = (v1 << 24) | (v2 << 16) | (v3 << 8) | v4;
- return(value);
- }
-
- struct hostent
- *gethostbyname(char *name)
- {
- struct machinfo *mp;
- int mnum;
- unsigned long now;
- static struct hostent ht;
- extern int pfs_debug;
-
- mp = Shostlook(name);
- if(!mp || (!mp->hostip[0])) { /* DNS lookup */
- #ifdef DEBUG
- if (pfs_debug)
- fprintf(stderr, "Domain name lookup of %s\n", name);
- #endif
- mnum = Sdomain(name); /* start a DNS lookup */
- now = time(NULL) + NS_TIMEOUT;
- while(now > time(NULL)) {
- int i, class, dat;
-
- Stask();
- i = Sgetevent(USERCLASS, &class, &dat);
- if(i == DOMOK) { /* domain lookup ok */
- mp = Slooknum(mnum);
- #ifdef DEBUG
- if (pfs_debug)
- fprintf(stderr, "Domain name lookup of %s Completed OK\n", name);
- #endif
- break;
- }
- }
- if(!mp) { /* get here if timeout */
- #ifdef DEBUG
- if (pfs_debug)
- fprintf(stderr, "Domain name lookup of %s Failed\n", name);
- #endif
- return(NULL);
- }
- }
- ht.h_addr = *((unsigned long *) mp->hostip);
- ht.h_length = 4;
- ht.h_addrtype = AF_INET;
- return(&ht);
-
- }
- #endif /* CUTCP */
-
- #ifdef GETENV
- /*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that: (1) source distributions retain this entire copyright
- * notice and comment, and (2) distributions including binaries display
- * the following acknowledgement: ``This product includes software
- * developed by the University of California, Berkeley and its contributors''
- * in the documentation or other materials provided with the distribution
- * and in all advertising materials mentioning features or use of this
- * software. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)getenv.c 5.7 (Berkeley) 6/1/90";
- #endif /* LIBC_SCCS and not lint */
-
- #include <stdlib.h>
- #include <stddef.h>
-
- /*
- * getenv --
- * Returns ptr to value associated with name, if any, else NULL.
- */
- char *
- getenv(name)
- char *name;
- {
- int offset;
- char *_findenv();
-
- return(_findenv(name, &offset));
- }
-
- /*
- * _findenv --
- * Returns pointer to value associated with name, if any, else NULL.
- * Sets offset to be the offset of the name/value combination in the
- * environmental array, for use by setenv(3) and unsetenv(3).
- * Explicitly removes '=' in argument name.
- *
- * This routine *should* be a static; don't use it.
- */
- char *
- _findenv(name, offset)
- register char *name;
- int *offset;
- {
- extern char **environ;
- register int len;
- register char **P, *C;
-
- for (C = name, len = 0; *C && *C != '='; ++C, ++len);
- for (P = environ; *P; ++P)
- if (!strncmp(*P, name, len))
- if (*(C = *P + len) == '=') {
- *offset = P - environ;
- return(++C);
- }
- return(NULL);
- }
- #endif
-